package org.example.domain.strategy.service.Raffle;

import org.example.domain.strategy.model.Raffle.FilterMatterEntity;
import org.example.domain.strategy.model.Raffle.RaffleFactorEntity;
import org.example.domain.strategy.model.Raffle.RuleActionEntity;
import org.example.domain.strategy.model.valobj.*;
import org.example.domain.strategy.repository.IStrategyRepository;
import org.example.domain.strategy.service.AbstractRaffleStrategy;
import org.example.domain.strategy.service.rule.Chain.ILogicChain;
import org.example.domain.strategy.service.rule.Chain.factory.DefaultLogicChainFactory;
import org.example.domain.strategy.service.rule.RuleFilter.Factory.DefaultFilterFactory;
import org.example.domain.strategy.service.rule.RuleFilter.ILogicFilter;
import org.example.domain.strategy.service.rule.Tree.Engine.IDecisionTreeEngine;
import org.example.domain.strategy.service.rule.Tree.Engine.factory.DefaultTreeFactory;
import org.example.types.common.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


//使用了工厂模式和策略模式,将黑名单过滤和权重过滤封装成一个接口的不同实现,然后利用工厂类将实现类的实例存到map中,客户端利用这个map来获取对应实现类

//抽象类的实现,用于定义实现细节
@Service
public class DefaultRaffleStrategy extends AbstractRaffleStrategy {

    Long score = 40500L;

    RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> result = null;

    @Autowired
    private IStrategyRepository strategyRepository;

    @Autowired
    private DefaultFilterFactory defaultFilterFactory;

    private Map<String,ILogicFilter> logicFilterGroup;

    @Autowired
    DefaultLogicChainFactory defaultLogicChainFactory;

    @Autowired
    private DefaultTreeFactory defaultTreeFactory;




    @Override
    public DefaultLogicChainFactory.StrategyAwardVO raffleLogicChain(Long strategyId, String userId) {
        ILogicChain logicChain = defaultLogicChainFactory.openLogicChain(strategyId);
        DefaultLogicChainFactory.StrategyAwardVO chainStrategyAwardVO  = logicChain.logic(strategyId, userId);
        return chainStrategyAwardVO;
    }



    @Override
    public DefaultTreeFactory.StrategyAwardVO raffleLogicTree(Long strategyId, Integer awardId, String userId) {
        StrategyAwardRuleModelVO strategyAwardRuleModelVO = strategyRepository.queryStrategyAwardRuleModelVO(strategyId, awardId);
        if (null == strategyAwardRuleModelVO) {
            return DefaultTreeFactory.StrategyAwardVO.builder().awardId(awardId).build();
        }
        RuleTreeVO ruleTreeVO = strategyRepository.queryRuleTreeVOByTreeId(strategyAwardRuleModelVO.getRuleModels());
        if (null == ruleTreeVO) {
            throw new RuntimeException("存在抽奖策略配置的规则模型 Key，未在库表 rule_tree、rule_tree_node、rule_tree_line 配置对应的规则树信息 " + strategyAwardRuleModelVO.getRuleModels());
        }
        IDecisionTreeEngine engine= defaultTreeFactory.openLogicTree(ruleTreeVO);
        DefaultTreeFactory.StrategyAwardVO treeStrategyAwardVO = engine.pocess(userId, strategyId, String.valueOf(awardId));
        return treeStrategyAwardVO;
    }


    @Override
    public DefaultTreeFactory.StrategyAwardVO raffleLogicTree(Long strategyId, Integer awardId, String userId, Date endDateTime) {
        StrategyAwardRuleModelVO strategyAwardRuleModelVO = strategyRepository.queryStrategyAwardRuleModelVO(strategyId, awardId);
        if (null == strategyAwardRuleModelVO) {
            return DefaultTreeFactory.StrategyAwardVO.builder().awardId(awardId).build();
        }
        RuleTreeVO ruleTreeVO = strategyRepository.queryRuleTreeVOByTreeId(strategyAwardRuleModelVO.getRuleModels());
        if (null == ruleTreeVO) {
            throw new RuntimeException("存在抽奖策略配置的规则模型 Key，未在库表 rule_tree、rule_tree_node、rule_tree_line 配置对应的规则树信息 " + strategyAwardRuleModelVO.getRuleModels());
        }
        IDecisionTreeEngine engine= defaultTreeFactory.openLogicTree(ruleTreeVO);
        DefaultTreeFactory.StrategyAwardVO treeStrategyAwardVO = engine.pocess(userId, strategyId, String.valueOf(awardId),endDateTime);
        return treeStrategyAwardVO;
    }

    //获取指定消息的延迟队列
    @Override
    public StrategyAwardStockKeyVO takeQueueValue() {
        //在这里用strategyRepository封装获取消息的函数是因为redis操作只能在infrastructure中操作,而没法在domain里面直接操做
        return strategyRepository.takeQueueValue();


    }

    @Override
    public void updateStrategyAwardStock(Long strategyId, String awardId) {
        strategyRepository.updateStrategyAwardStock(strategyId,awardId);

    }

    /**
     * 根据TreeId列表查询对应次数锁节点的次数锁值
     * @param treeIds treeId列表
     * @return
     */
    @Override
    public Map<String, Integer> queryRuleLockValue(String[] treeIds) {
        String ruleKey = "rule_lock";
        Map<String, Integer> map = new HashMap<>();
        for (String treeId : treeIds){
                Integer ruleLockValue = strategyRepository.queryRuleValueByTreeIdAndRuleKey(treeId,ruleKey);
                map.put(treeId ,ruleLockValue);
        }
        return map;
    }

    public List<RuleWeightVO> queryAwardRuleWeightByStrategyId(Long strategyId) {
         return strategyRepository.queryAwardRuleWeightByStrategyId(strategyId);


    }

    @Override
    public List<RuleWeightVO> queryAwardRuleWeightByActivityId(Long activityId) {
        Long strategyId = strategyRepository.queryStrategyIdByActivityId(activityId);

        return queryAwardRuleWeightByStrategyId(strategyId);
    }
}


